package cn.com.yd.commons.grpc.util;

import cn.com.yd.commons.grpc.Request;
import cn.com.yd.commons.grpc.Response;
import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.ByteString;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.reflect.FastClass;
import net.sf.cglib.reflect.FastMethod;

/**
 * Grpc工具类
 * @author 李庆海
 *
 */
public class GrpcHelper {

    /**
     * 转换成GRPC方法需要的参数
     *
     * @param bean   Spring管理的bean实例名称
     * @param method 要执行的业务方法
     * @param args   业务方法的参数，可以为null
     * @return
     */
    public static Request toRequest(String bean, String method, Object[] args) {
        JSONObject json = new JSONObject();
        json.put("bean", bean);
        json.put("method", method);
        if (null != args) {
            json.put("args", args);
        }
        byte[] bytes = ProtobufUtils.serialize(json);
        return Request.newBuilder().setRequest(ByteString.copyFrom(bytes)).build();
    }

    /**
     * 将GRPC方法的请求参数转换成JSONObject
     *
     * @param request GRPC方法的请求参数
     * @return
     */
    public static JSONObject toJSONObject(Request request) {
        return ProtobufUtils.deserialize(request.getRequest().toByteArray(), JSONObject.class);
    }

    /**
     * 将响应结果转换成JSONObject
     * @param response 响应结果
     * @return
     */
    public static JSONObject toJSONObject(Response response) {
        return ProtobufUtils.deserialize(response.getReponse().toByteArray(), JSONObject.class);
    }


    public static JSONObject success() {
        JSONObject json = new JSONObject();
        json.put("state", true);
        json.put("msg", "成功");
        json.put("data", null);
        return json;
    }

    /**
     * 执行具体的业务方法并返回执行结果
     *
     * @param bean   Spring管理的bean实例
     * @param method 要执行的业务方法
     * @param args   业务方法的参数，可以为null
     * @return
     */
    public static Object execute(Object bean, String method, Object[] args) {
        Object result = null;
        try {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(bean.getClass());
            FastClass serviceFastClass = FastClass.create(bean.getClass());
            Class<?>[] argTypes = null;
            if (args != null) {
                argTypes = new Class[args.length];
                for (int i = 0; i < args.length; i++) {
                    Class<?> type = args[i].getClass();
                    argTypes[i] = type;
                }
            }
            FastMethod serviceFastMethod = serviceFastClass.getMethod(method, argTypes);
            result = serviceFastMethod.invoke(bean, args);
        } catch (Exception e) {
            result = e;
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 将执行结果转换成Response
     * @param result 执行结果
     * @return
     */
    public static Response toResponse(Object result) {
        JSONObject json = null;
        if (result instanceof JSONObject) {
            json = (JSONObject) result;
        } else {
            json = new JSONObject();
            if (result instanceof Throwable) {
                json.put("state", false);
                json.put("msg", "失败");
                json.put("data", ((Throwable) result).getMessage());
            } else {
                json.put("state", true);
                json.put("msg", "成功");
                json.put("data", result);
            }
        }
        return Response.newBuilder().setReponse(ByteString.copyFrom(ProtobufUtils.serialize(json))).build();
    }
}
